home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1995-11-16 | 25.9 KB | 759 lines | [TEXT/.Ob4] |
- Syntax10.Scn.Fnt
- MODULE Browser; (* J.Templ 16.8.89/16.12.92 *) (* << RC 21.12.92, mah 12.1.94 *)
- mah 16.11.95 error removed with 'xxx = SYS.PTR' (1)
- IMPORT SYSTEM, Files, Texts, MenuViewers, TextFrames, Oberon;
- CONST
- OptionChar = "/";
- IdBufLeng = 12000;
- IdBufLim = IdBufLeng - 100;
- maxImps = 30;
- SFtag = 0F7X;
- firstStr = 16;
- (*object modes*)
- Var = 1; Ind = 2; Con = 3; Fld = 4; Typ = 5; XProc = 6;
- CProc = 7; IProc = 8; Mod = 9; Head = 10; TProc = 11;
- (*Structure forms*)
- Undef = 0; Byte = 1; Bool = 2; Char = 3; SInt = 4; Int = 5; LInt = 6;
- Real = 7; LReal = 8; Set = 9; String = 10; NilTyp = 11; NoTyp = 12;
- Pointer = 13; ProcTyp = 14; Array = 15; DynArr = 16; Record = 17;
- TYPE
- Object = POINTER TO ObjDesc;
- Struct = POINTER TO StrDesc;
- ObjDesc = RECORD
- left, right, link: Object;
- typ: Struct;
- name: INTEGER;
- mode: SHORTINT;
- marked: BOOLEAN;
- a0, a1: LONGINT; (* a0 gives org in module list *)
- next: Object; (* next module *)
- END ;
- StrDesc = RECORD
- form, mno, ref, level: SHORTINT;
- n, size, adr: LONGINT; (* adr gives org in type hierarchy *)
- BaseTyp: Struct;
- link, strobj: Object;
- sub, next: Struct (* type hierarchy *)
- END ;
- W: Texts.Writer;
- id: INTEGER;
- err: BOOLEAN;
- universe, topScope: Object;
- undftyp, bytetyp, booltyp, chartyp, sinttyp, inttyp, linttyp,
- realtyp, lrltyp, settyp, stringtyp, niltyp, notyp, sysptrtyp: Struct;
- nofGmod: INTEGER; (*nof imports*)
- option: CHAR;
- first, showObj: BOOLEAN;
- GlbMod: ARRAY maxImps OF Object;
- IdBuf: ARRAY IdBufLeng OF CHAR;
- types: Struct;
- symFileExt: ARRAY 8 OF CHAR;
- (*needed for detecting import of SYSTEM *)
- syspos: LONGINT;
- impSystem: BOOLEAN; (* insert "SYSTEM, " at imppos or " IMPORT SYSTEM; cr cr" at -imppos *)
- PROCEDURE Ws(s: ARRAY OF CHAR); BEGIN Texts.WriteString(W, s) END Ws;
- PROCEDURE Wch(ch: CHAR); BEGIN Texts.Write(W, ch) END Wch;
- PROCEDURE Wln; BEGIN Texts.WriteLn(W) END Wln;
- PROCEDURE WriteName(obj: Object);
- VAR name: ARRAY 32 OF CHAR; i, n: INTEGER;
- BEGIN n := obj^.name;
- i := -1; REPEAT INC(i); name[i] := IdBuf[n + i] UNTIL name[i] = 0X;
- Ws(name)
- END WriteName;
- PROCEDURE WAdr(obj: Object); (* << *)
- VAR adr: LONGINT;
- BEGIN
- IF option = "X" THEN
- adr := obj^.a0;
- IF adr < 0 THEN adr := -1-adr;
- IF adr DIV 32 = 16 THEN Texts.Write(W, "R") ELSE Texts.Write(W, "F") END;
- Texts.WriteInt(W, adr MOD 32, 0)
- ELSE
- Texts.WriteInt(W, adr, 0)
- END;
- Wch(" ")
- END
- END WAdr;
- PROCEDURE Indent(i: INTEGER);
- BEGIN WHILE i > 0 DO Wch(9X); DEC(i) END
- END Indent;
- PROCEDURE WriteRecords(typ: Struct; i: INTEGER);
- BEGIN
- WHILE typ # NIL DO
- Indent(i);
- WriteName(GlbMod[typ.mno]); Wch("."); WriteName(typ.strobj);
- Wln; WriteRecords(typ^.sub, i + 1);
- typ := typ^.next
- END
- END WriteRecords;
- PROCEDURE WriteModules(m: Object);
- BEGIN
- WHILE m # NIL DO
- m^.a0 := W.buf.len;
- WriteName(m); Wln;
- m := m^.next
- END
- END WriteModules;
- PROCEDURE^ WriteType(typ: Struct; i: INTEGER);
- PROCEDURE WriteBase(typ: Struct);
- VAR base: Struct;
- BEGIN base := typ^.BaseTyp;
- IF (base # NIL) & (base^.strobj^.marked OR (option = "X")) THEN
- Ws(" ("); WriteType(typ^.BaseTyp, 0);
- IF option = "x" THEN WriteBase(typ^.BaseTyp) END ;
- Wch(")")
- END;
- END WriteBase;
- PROCEDURE WriteFields(VAR obj: Object; i: INTEGER);
- VAR typ: Struct; mode: INTEGER;
- BEGIN typ := obj^.typ; mode := obj^.mode;
- LOOP
- WAdr(obj); WriteName(obj);
- IF obj^.marked THEN Wch("-") END ;
- obj := obj^.link;
- IF (obj = NIL) OR (obj^.mode # mode) OR (obj^.typ # typ) THEN EXIT END ;
- Ws(", ")
- END ;
- Ws(": "); WriteType(typ, i + 1)
- END WriteFields;
- PROCEDURE WriteParams(param: Object; res: Struct);
- BEGIN
- IF (param # NIL) OR (res # notyp) THEN
- Ws(" (");
- WHILE (param # NIL) DO
- IF param.mode = Ind THEN Ws("VAR ") END ;
- IF param.name = 0 THEN
- WriteType(param.typ, 0);
- param := param.link;
- IF param # NIL THEN Ws(", ") END
- ELSE
- WriteFields(param, 0);
- IF param # NIL THEN Ws("; ") END
- END
- END ;
- Wch(")");
- END ;
- IF res # notyp THEN Ws(": "); WriteType(res, 0) END
- END WriteParams;
- PROCEDURE WriteFieldList(obj: Object; i: INTEGER);
- BEGIN
- WHILE (obj # NIL) & (obj^.mode = Fld) DO
- Indent(i); WriteFields(obj, i); Wch(";"); Wln
- END ;
- WHILE (obj # NIL) & (obj^.mode = TProc) DO
- Indent(i);
- IF option = "X" THEN Texts.WriteInt(W, obj^.a0 MOD 10000H,1); Wch(" ");
- Texts.WriteInt(W, obj^.a0 DIV 10000H,1); Wch(" ")
- END ;
- Ws("PROCEDURE (");
- IF obj^.right^.mode = Ind THEN Ws("VAR ") END ;
- WAdr(obj^.right);
- WriteName(obj^.right);
- Ws(": ");
- WriteName(obj^.right^.typ^.strobj);
- Ws(") ");
- WriteName(obj);
- WriteParams(obj^.right^.link, obj^.typ);
- Wch(";"); Wln;
- obj := obj^.link
- END
- END WriteFieldList;
- PROCEDURE WriteInstVars(typ: Struct; i: INTEGER);
- BEGIN
- IF typ # NIL THEN
- IF option = "x" THEN WriteInstVars(typ^.BaseTyp, i) END;
- WriteFieldList(typ^.link, i);
- END
- END WriteInstVars;
- PROCEDURE WriteForm(typ: Struct; i: INTEGER);
- VAR param, p: Object;
- BEGIN
- IF typ^.form = Record THEN
- Ws("RECORD"); WriteBase(typ);
- IF option = "X" THEN Wch(" "); Texts.WriteInt(W, typ^.size, 1); Wch(" ") END ;
- IF (typ^.link # NIL) OR (option = "x") THEN Wln; WriteInstVars(typ, i); Indent(i - 1) ELSE Wch(" ") END ;
- Ws("END ")
- ELSIF typ^.form = Array THEN
- Ws("ARRAY "); Texts.WriteInt(W, typ^.n, 0); Ws(" OF "); WriteType(typ^.BaseTyp, i)
- ELSIF typ^.form = DynArr THEN
- Ws("ARRAY OF "); WriteType(typ^.BaseTyp, i)
- ELSIF typ^.form = Pointer THEN
- Ws("POINTER TO "); WriteType(typ^.BaseTyp, i)
- ELSIF typ^.form = ProcTyp THEN
- Ws("PROCEDURE");
- WriteParams(typ^.link, typ^.BaseTyp)
- END
- END WriteForm;
- PROCEDURE WriteType(typ: Struct; i: INTEGER);
- BEGIN
- IF typ^.strobj # NIL THEN
- IF (typ = bytetyp) OR (typ = sysptrtyp) THEN impSystem := TRUE END ;
- IF (typ^.mno > 1) OR ((typ^.mno = 1) & showObj) THEN WriteName(GlbMod[typ^.mno]); Wch(".") END ;
- WriteName(typ^.strobj)
- ELSE WriteForm(typ, i)
- END
- END WriteType;
- PROCEDURE WriteProc(obj: Object);
- VAR param: Object; i: LONGINT;
- BEGIN
- IF (option = "X") & (obj^.mode # CProc) THEN Texts.WriteInt(W, obj^.a0, 2); Indent(1) END ;
- Ws("PROCEDURE ");
- IF obj^.mode = CProc THEN Wch("-") ELSIF obj^.mode = IProc THEN Wch("+") END;
- WriteName(obj);
- WriteParams(obj^.link, obj^.typ);
- IF obj^.mode = CProc THEN Wch(" "); i := 0;
- WHILE i < obj^.a1 DO
- Texts.WriteInt(W, ORD(IdBuf[obj^.a0 + i]), 1); INC(i);
- IF i < obj^.a1 THEN Ws(", ") END
- END ;
- END ;
- Wch(";")
- END WriteProc;
- PROCEDURE WriteVal(obj: Object);
- VAR i: INTEGER; lr: LONGREAL; s: SET; ch: CHAR;
- BEGIN
- CASE obj.typ^.form OF
- SInt, Int, LInt: Texts.WriteInt(W, obj^.a0, 0) |
- Real: Texts.WriteReal(W, SYSTEM.VAL(REAL, obj^.a0), 16) |
- LReal: SYSTEM.MOVE(SYSTEM.ADR(obj^.a0), SYSTEM.ADR(lr), 8); Texts.WriteLongReal(W, lr, 23) |
- Bool: IF obj^.a0 = 0 THEN Ws("FALSE") ELSE Ws("TRUE") END |
- Char: IF (obj^.a0 >= 32) & (obj^.a0 <= 126) THEN
- Wch(22X); Wch(CHR(obj^.a0)); Wch(22X)
- ELSE
- i := SHORT(obj^.a0 DIV 16);
- IF i > 9 THEN Wch(CHR(55 + i)) ELSE Wch(CHR(48 + i)) END;
- i := SHORT(obj^.a0 MOD 16);
- IF i > 9 THEN Wch(CHR(55 + i)) ELSE Wch(CHR(48 + i)) END;
- Wch("X")
- END |
- Set: Wch("{"); i := 0; s := SYSTEM.VAL(SET, obj^.a0);
- WHILE i <= MAX(SET) DO
- IF MAX(SET)-i IN s THEN Texts.WriteInt(W, i, 0); EXCL(s, MAX(SET)-i);
- IF s # {} THEN Ws(", ") END
- END ;
- INC(i)
- END ;
- Wch("}") |
- NilTyp: Ws("NIL") |
- String: i := SHORT(obj^.a0); ch := IdBuf[i]; Wch(22X);
- WHILE ch # 0X DO Wch(ch); INC(i); ch := IdBuf[i] END ;
- Wch(22X)
- END
- END WriteVal;
- PROCEDURE WriteObject(VAR obj: Object; mode: INTEGER);
- BEGIN
- IF mode = Con THEN
- IF first THEN Indent(1); Ws("CONST"); Wln; first := FALSE END;
- Indent(2); WriteName(obj); Ws(" = "); WriteVal(obj); Wch(";");
- Wln
- ELSIF mode = Var THEN
- IF first THEN Indent(1); Ws("VAR"); Wln; first := FALSE END;
- Indent(2);
- LOOP
- WAdr(obj); WriteName(obj);
- IF obj^.marked THEN Wch("-") END ;
- IF (obj^.right = NIL) OR (obj^.right^.mode # obj^.mode) OR (obj^.right^.typ # obj^.typ) THEN EXIT END ;
- Ws(", "); obj := obj^.right
- END ;
- Ws(": "); WriteType(obj^.typ, 3); Wch(";");
- Wln
- ELSIF (mode = Typ) & (obj^.marked) THEN
- IF first THEN Indent(1); Ws("TYPE"); Wln; first := FALSE END;
- Indent(2); WriteName(obj); Ws(" = ");
- IF obj^.typ^.strobj # obj THEN WriteType(obj^.typ, 0) (* alias type *)
- ELSE WriteForm(obj^.typ, 3)
- END ;
- Wch(";"); Wln;
- IF showObj THEN
- IF (obj^.typ^.form = Pointer) & (obj^.typ^.BaseTyp^.strobj # NIL) THEN
- WriteObject(obj^.typ^.BaseTyp^.strobj, obj^.typ^.BaseTyp^.strobj.mode)
- END
- ELSIF (obj^.typ^.form # Pointer) OR (obj^.typ^.BaseTyp = NIL) OR (obj^.typ^.BaseTyp^.strobj = NIL) THEN Wln (* mah (1) *)
- END
- ELSIF mode IN {XProc, IProc, CProc} THEN first := FALSE; Indent(1); WriteProc(obj); Wln
- ELSIF mode = Mod THEN
- IF first THEN Indent(1); Ws("IMPORT "); first := FALSE; syspos := W.buf.len ELSE Ws(", ") END;
- WriteName(obj);
- IF option = "X" THEN Texts.WriteHex(W, obj^.a1) END
- END
- END WriteObject;
- PROCEDURE WriteScope(obj: Object; mode: INTEGER);
- BEGIN
- first := TRUE;
- WHILE obj # NIL DO
- IF (obj.mode = mode) OR ((mode = XProc) & (obj.mode IN {CProc, IProc})) THEN WriteObject(obj, mode) END ;
- obj := obj^.right
- END ;
- IF ~first THEN
- IF mode = Mod THEN Wch(";"); Wln END ;
- Wln
- END
- END WriteScope;
- PROCEDURE ReorderTypes(mod: Object); (* make <pointer, record> pairs *)
- VAR p, q, head, h: Object; typ: Struct;
- BEGIN q := mod^.link;
- NEW(head); head^.right := q;
- WHILE q # NIL DO
- IF (q.mode = Typ) & (q^.typ^.form = Pointer) & (q^.typ^.BaseTyp # NIL) & (q^.typ^.BaseTyp^.strobj # NIL) THEN (* mah (1) *)
- p := head; typ := q^.typ^.BaseTyp;
- WHILE (p^.right # NIL) & ((p^.right^.mode # Typ) OR (p^.right^.typ # typ)) DO p := p^.right END ;
- IF p^.right # NIL THEN
- h := p^.right; p^.right := h^.right; h^.right := q^.right; q^.right := h
- END
- END ;
- q := q^.right
- END ;
- mod^.link := head^.right
- END ReorderTypes;
- PROCEDURE WriteModule(mod: Object);
- BEGIN
- Ws("DEFINITION "); WriteName(mod);
- IF option = "X" THEN Texts.WriteHex(W, mod^.a1) END ;
- Wch(";"); Wln; Wln;
- syspos := - W.buf.len; impSystem := FALSE;
- WriteScope(mod^.link, Mod);
- WriteScope(mod^.link, Con);
- ReorderTypes(mod); WriteScope(mod^.link, Typ);
- WriteScope(mod^.link, Var);
- WriteScope(mod^.link, CProc);
- WriteScope(mod^.link, XProc);
- Ws("END "); WriteName(mod); Wch(".")
- END WriteModule;
- PROCEDURE Diff(i, j: INTEGER): INTEGER;
- VAR d: INTEGER; ch: CHAR;
- BEGIN
- REPEAT ch := IdBuf[i]; d := ORD(ch) - ORD(IdBuf[j]); INC(i); INC(j)
- UNTIL (d # 0) OR (ch = 0X);
- RETURN d
- END Diff;
- PROCEDURE Index(name: ARRAY OF CHAR): INTEGER;
- VAR id0, j: INTEGER; ch: CHAR; (*enter identifier*)
- BEGIN
- id0 := id; j := 0;
- IF id < IdBufLim THEN
- REPEAT ch := name[j]; IdBuf[id] := ch; INC(id); INC(j)
- UNTIL ch = 0X
- ELSE err := TRUE
- END ;
- RETURN id0
- END Index;
- PROCEDURE Insert(name: INTEGER; VAR obj: Object);
- VAR d: INTEGER; ob0, ob1: Object;
- BEGIN
- ob0 := topScope; ob1 := ob0^.right; d := 1;
- LOOP
- IF ob1 # NIL THEN
- d := Diff(name, ob1^.name);
- IF d < 0 THEN ob0 := ob1; ob1 := ob0^.left
- ELSIF d > 0 THEN ob0 := ob1; ob1 := ob0^.right
- ELSE ob1 := NIL (* already defined, cause duplication *)
- END
- ELSE (*insert*) NEW(ob1);
- IF d < 0 THEN ob0^.left := ob1 ELSE ob0^.right := ob1 END ;
- ob1^.left := NIL; ob1^.right := NIL; ob1^.name := name;
- ob1^.marked := FALSE; EXIT
- END
- END ;
- obj := ob1
- END Insert;
- PROCEDURE InsertSubClass(base, sub: Struct);
- VAR prev: Struct;
- PROCEDURE Less(typ1, typ2: Struct): BOOLEAN; (* return typ1 < typ2 *)
- VAR i: INTEGER;
- BEGIN
- i := Diff(GlbMod[typ1^.mno]^.name, GlbMod[typ2^.mno]^.name);
- IF i < 0 THEN RETURN TRUE
- ELSIF i = 0 THEN RETURN Diff(typ1^.strobj^.name, typ2^.strobj^.name) < 0
- ELSE RETURN FALSE
- END
- END Less;
- BEGIN
- IF base = NIL THEN base := types END ;
- prev := base^.sub;
- IF (prev = NIL) OR Less(sub, prev) THEN
- sub^.next := base^.sub; base^.sub := sub
- ELSE
- WHILE (prev^.next # NIL) & Less(prev^.next, sub) DO prev := prev^.next END;
- sub^.next := prev^.next; prev^.next := sub
- END
- END InsertSubClass;
- PROCEDURE InsertImport(obj, root: Object; VAR old: Object);
- VAR ob0, ob1: Object; d: INTEGER;
- BEGIN ob0 := root; ob1 := ob0^.right; d := 1;
- LOOP
- IF ob1 # NIL THEN
- d := Diff(obj^.name, ob1^.name);
- IF d = 0 THEN old := ob1; EXIT
- ELSE ob0 := ob1; ob1 := ob1^.right
- END
- ELSE ob1 := obj; ob0^.right := ob1;
- ob1^.left := NIL; ob1^.right := NIL; old := NIL; EXIT
- END
- END
- END InsertImport;
- PROCEDURE Append(VAR d: ARRAY OF CHAR; s: ARRAY OF CHAR);
- VAR i, j: INTEGER; ch: CHAR;
- BEGIN
- i := 0; WHILE d[i] # 0X DO INC(i) END ;
- j := 0; REPEAT ch := s[j]; d[i] := ch; INC(i); INC(j) UNTIL ch = 0X
- END Append;
- PROCEDURE ReadSym(name: ARRAY OF CHAR; VAR obj: Object);
- VAR i, j, m, h1, h2, s, class: INTEGER; k: LONGINT;
- nofLmod, strno, parlev, fldlev: INTEGER;
- old, mod: Object;
- typ: Struct;
- ch: CHAR;
- si: SHORTINT;
- xval: REAL; yval: LONGREAL;
- LocMod: ARRAY maxImps OF Object;
- struct: ARRAY 255 OF Struct; (* << RC *)
- param, lastpar, fldlist, lastfld: ARRAY 6 OF Object;
- FileName: ARRAY 32 OF CHAR;
- SymFile: Files.File;
- SF: Files.Rider;
- (* << RC *)
- PROCEDURE ReadInt(VAR i: INTEGER); VAR k: LONGINT; BEGIN Files.ReadNum(SF, k); i := SHORT(k) END ReadInt;
- PROCEDURE ReadXInt(VAR k: LONGINT); BEGIN Files.ReadNum(SF, k) END ReadXInt;
- PROCEDURE ReadLInt(VAR k: LONGINT); BEGIN Files.ReadNum(SF, k) END ReadLInt;
- PROCEDURE ReadId;
- VAR i: INTEGER; ch: CHAR;
- BEGIN i := id;
- REPEAT
- Files.Read(SF, ch); IdBuf[i] := ch; INC(i)
- UNTIL ch = 0X;
- id := i
- END ReadId;
- PROCEDURE Err(s: ARRAY OF CHAR);
- BEGIN
- Ws(name); Ws(" -- "); Ws(s);
- Wln; Texts.Append(Oberon.Log, W.buf)
- END Err;
- PROCEDURE reverseList(p: Object);
- VAR q, r: Object;
- BEGIN q := NIL;
- WHILE p # NIL DO
- r := p^.link; p^.link := q; q := p; p := r
- END
- END reverseList;
- PROCEDURE AppendObj(VAR p: Object; obj: Object);
- VAR r: Object;
- BEGIN
- IF p = NIL THEN p := obj
- ELSE r := p; WHILE r^.link # NIL DO r := r^.link END ;
- r^.link := obj
- END
- END AppendObj;
- PROCEDURE FlipBits (i: LONGINT): LONGINT;
- VAR s, d: SET;
- BEGIN
- s := SYSTEM.VAL(SET, i); d := {}; i := 0;
- WHILE i < 32 DO IF i IN s THEN INCL(d, 31-i) END; INC(i) END;
- RETURN SYSTEM.VAL(LONGINT, d)
- END FlipBits;
- BEGIN (* ReadSym *)
- err := TRUE;
- nofLmod := 0; strno := firstStr;
- parlev := 0; fldlev := 0;
- COPY(name, FileName); Append(FileName, symFileExt);
- SymFile := Files.Old(FileName);
- IF SymFile # NIL THEN
- Files.Set(SF, SymFile, 0); Files.Read(SF, ch);
- IF ch = SFtag THEN
- struct[Undef] := undftyp; struct[Byte] := bytetyp;
- struct[Bool] := booltyp; struct[Char] := chartyp;
- struct[SInt] := sinttyp; struct[Int] := inttyp;
- struct[LInt] := linttyp; struct[Real] := realtyp;
- struct[LReal] := lrltyp; struct[Set] := settyp;
- struct[String] := stringtyp; struct[NilTyp] := niltyp;
- struct[NoTyp] := notyp; struct[Pointer] := sysptrtyp; (*:*)
- LOOP (*read next item from symbol file*)
- Files.Read(SF, ch); class := ORD(ch);
- IF SF.eof THEN EXIT END ;
- CASE class OF
- 0..7, 23, 25: (*object*) (*:*)
- NEW(obj); m := 0;
- ReadInt(s); obj^.typ := struct[s];
- CASE class OF
- 1: obj^.mode := Con;
- CASE obj^.typ^.form OF
- | 1,2,3: Files.Read(SF, ch); obj^.a0 := ORD(ch)
- | 4: Files.Read(SF, si); obj^.a0 := si
- | 5: ReadXInt(obj^.a0)
- | 6: ReadLInt(obj^.a0) (* << RC *)
- | 9: ReadLInt(obj^.a0); obj^.a0 := FlipBits(obj^.a0) (* << mmb *)
- | 7: Files.ReadReal(SF, SYSTEM.VAL(REAL, obj^.a0)) (* << mmb *)
- | 8: Files.ReadLReal(SF, yval);
- SYSTEM.MOVE(SYSTEM.ADR(yval), SYSTEM.ADR(obj^.a0), 8); (* << mmb *)
- | 10: obj^.a0 := id; ReadId
- | 11: (*NIL*)
- END
- |2,3: obj^.mode := Typ; ReadInt(m);
- IF obj^.typ^.strobj = NIL THEN obj^.typ^.strobj := obj END;
- obj^.marked := class = 2
- |4, 23: obj^.mode := Var; ReadLInt(obj^.a0); obj^.marked := (class = 23) (* << RC *)
- |5, 6, 7, 25: (*:*)
- h1 := 0; h2 := 0; (*:*)
- IF class = 5 THEN obj^.mode := IProc; ReadInt(h1)
- ELSIF class = 6 THEN obj^.mode := XProc; ReadInt(h1)
- ELSIF class = 25 THEN obj^.mode := TProc;
- ReadInt(s); ReadInt(h1); ReadInt(h2);
- typ := struct[s]
- ELSE obj^.mode := CProc; Files.Read(SF, ch); i := ORD(ch);
- obj^.a0 := id; obj^.a1 := i;
- WHILE i > 0 DO Files.Read(SF, IdBuf[id]); INC(id); DEC(i) END
- END ;
- IF class # 7 THEN obj^.a0 := h1 + h2 * 10000H END ;
- reverseList(lastpar[parlev]);
- obj^.link := param[parlev]^.right; DEC(parlev)
- END ;
- obj^.name := id; ReadId;
- IF (class = 6) & (fldlev > 0) THEN InsertImport(obj, fldlist[fldlev], old)
- ELSIF class = 25 THEN obj^.right := obj^.link; obj^.link:= NIL; AppendObj(typ^.link, obj) (*:*)
- ELSE
- IF IdBuf[obj^.name] # 0X THEN
- InsertImport(obj, LocMod[m], old);
- IF (old # NIL) & (obj^.mode = Typ) THEN struct[s] := old^.typ
- ELSIF (obj^.mode = Typ) & (obj^.typ^.form = Record) & (obj^.typ^.strobj = obj) THEN
- InsertSubClass(typ^.BaseTyp, typ)
- END
- END
- END
- | 8..12: (*structure*)
- NEW(typ); typ^.strobj := NIL; typ^.ref := 0;
- ReadInt(s); typ^.BaseTyp := struct[s];
- ReadInt(s); typ^.mno := SHORT(SHORT(LocMod[s]^.a0));
- CASE class OF
- 8: typ^.form := Pointer; typ^.size := 4; typ^.n := 0
- | 9: typ^.form := ProcTyp; typ^.size := 4;
- reverseList(lastpar[parlev]);
- typ^.link := param[parlev]^.right; DEC(parlev)
- | 10: typ^.form := Array; ReadLInt(typ^.size); typ^.n := typ^.size DIV typ^.BaseTyp^.size
- | 11: typ^.form := DynArr; ReadLInt(typ^.size); ReadXInt(typ^.adr)
- | 12: typ^.form := Record;
- ReadLInt(typ^.size);
- reverseList(lastfld[fldlev]);
- typ^.link := fldlist[fldlev]^.right; DEC(fldlev);
- typ^.level := typ^.BaseTyp^.level;
- IF typ^.BaseTyp = notyp THEN typ^.BaseTyp := NIL END ;
- ReadXInt(typ^.adr); (*of descriptor*)
- END ;
- struct[strno] := typ; INC(strno)
- | 13: (*parameter list start*)
- NEW(obj); obj^.mode := Head; obj^.right := NIL;
- IF parlev < 6 THEN INC(parlev); param[parlev] := obj; lastpar[parlev] := NIL
- ELSE RETURN
- END
- | 14, 15: (*parameter*)
- NEW(obj);
- IF class = 14 THEN obj^.mode := Var ELSE obj^.mode := Ind END ;
- ReadInt(s); obj^.typ := struct[s];
- ReadXInt(obj^.a0); obj^.name := id; ReadId;
- InsertImport(obj, param[parlev], old);
- obj^.link := lastpar[parlev]; lastpar[parlev] := obj
- | 16: (*start field list*)
- NEW(obj); obj^.mode := Head; obj^.right := NIL;
- IF fldlev < 5 THEN INC(fldlev); fldlist[fldlev] := obj; lastfld[fldlev] := NIL
- ELSE RETURN
- END
- | 17, 24: (*field, rfield*)
- NEW(obj); obj^.mode := Fld; ReadInt(s);
- obj^.marked := (class = 24);
- obj^.typ := struct[s]; ReadLInt(obj^.a0);
- obj^.name := id; ReadId;
- obj^.link := lastfld[fldlev]; lastfld[fldlev] := obj;
- InsertImport(obj, fldlist[fldlev], old)
- | 18, 19: (*hidden pointer field, hidden procedure field *)
- ReadLInt(k)
- | 20: (*fixup pointer typ*)
- ReadInt(s); typ := struct[s];
- ReadInt(s);
- IF typ^.BaseTyp = undftyp THEN typ^.BaseTyp := struct[s] END
- | 21: (*skip sysflag*)
- ReadInt(s); ReadInt(s)
- | 22: (*module anchor*)
- ReadLInt(k); m := id; ReadId; i := 0;
- WHILE (i < nofGmod) & (Diff(m, GlbMod[i]^.name) # 0) DO
- INC(i)
- END ;
- IF i < nofGmod THEN (*module already present*)
- IF k # GlbMod[i]^.a1 THEN Err("invalid module key"); RETURN END ;
- obj := GlbMod[i]
- ELSE NEW(obj);
- obj^.mode := Head; obj^.name := m;
- obj^.a1 := k; obj^.a0 := nofGmod; obj^.right := NIL;
- IF nofGmod < maxImps THEN GlbMod[nofGmod] := obj; INC(nofGmod)
- ELSE RETURN
- END
- END ;
- IF nofLmod < 20 THEN LocMod[nofLmod] := obj; INC(nofLmod)
- ELSE Err("too many imports"); RETURN
- END ;
- IF nofLmod > 1 THEN NEW(mod); mod^.name := obj^.name; mod^.mode := Mod; mod^.a1 := k;
- InsertImport(mod, LocMod[0], old)
- END
- | 26: (*nofmethods*)
- ReadInt(s); ReadInt(h1); struct[s].n := h1
- | 27: (*hidden method*)
- ReadInt(s); ReadInt(s); ReadInt(s)
- ELSE Err("invalid symbol file"); RETURN
- END
- END (*LOOP*) ;
- Insert(Index(name), obj);
- obj^.mode := Mod; obj^.link := LocMod[0]^.right;
- obj^.a0 := LocMod[0]^.a0; obj^.a1 := LocMod[0]^.a1; obj^.typ := notyp;
- ELSE Err("not a symbol file"); RETURN
- END
- ELSE Err("symbol file not found"); RETURN
- END;
- err := FALSE
- END ReadSym;
- PROCEDURE DisplayW(name: ARRAY OF CHAR);
- VAR mV: MenuViewers.Viewer; T: Texts.Text; x, y: INTEGER;
- BEGIN
- T := TextFrames.Text(""); Texts.Append(T, W.buf);
- IF (syspos # 0) & impSystem THEN
- IF syspos > 0 THEN Ws("SYSTEM, ") ELSE Wch(09X); Ws("IMPORT SYSTEM;"); Wln; Wln END;
- Texts.Insert(T, ABS(syspos), W.buf);
- syspos := 0
- END ;
- Oberon.AllocateUserViewer(Oberon.Mouse.X, x, y);
- mV := MenuViewers.New(
- TextFrames.NewMenu(name, "^Edit.Menu.Text"),
- TextFrames.NewText(T, 0),
- TextFrames.menuH, x, y)
- END DisplayW;
- PROCEDURE InitStruct(VAR typ: Struct; f: SHORTINT);
- BEGIN NEW(typ); typ^.form := f; typ^.ref := f; typ^.size := 1
- END InitStruct;
- PROCEDURE Init;
- PROCEDURE EnterTyp(name: ARRAY OF CHAR; form: SHORTINT; size: INTEGER; VAR res: Struct);
- VAR obj: Object; typ: Struct;
- BEGIN Insert(Index(name), obj);
- NEW(typ); obj^.mode := Typ; obj^.typ := typ;
- typ^.form := form; typ^.strobj := obj; typ^.size := size;
- typ^.mno := 0; typ^.ref := form; res := typ
- END EnterTyp;
- PROCEDURE OpenScope(level: INTEGER; owner: Object);
- VAR head: Object;
- BEGIN NEW(head);
- head^.mode := Head; head^.a0 := level; head^.link := owner;
- head^.left := topScope; head^.right := NIL; topScope := head
- END OpenScope;
- BEGIN
- IdBuf[0] := 0X; id := 1; topScope := NIL; OpenScope(0, NIL);
- EnterTyp("CHAR", Char, 1, chartyp);
- EnterTyp("SET", Set, 4, settyp);
- EnterTyp("REAL", Real, 4, realtyp);
- EnterTyp("INTEGER", Int, 2, inttyp);
- EnterTyp("LONGINT", LInt, 4, linttyp);
- EnterTyp("LONGREAL", LReal, 8, lrltyp);
- EnterTyp("SHORTINT", SInt, 1, sinttyp);
- EnterTyp("BOOLEAN", Bool, 1, booltyp);
- EnterTyp("SYSTEM.BYTE", Byte, 1, bytetyp);
- EnterTyp("SYSTEM.PTR", Pointer, 4, sysptrtyp); (*:*)
- universe := topScope; topScope^.right := NIL;
- nofGmod := 1; topScope^.name := 0; GlbMod[0] := topScope; OpenScope(0, NIL);
- NEW(types);
- END Init;
- PROCEDURE GetArgs(VAR S: Texts.Scanner);
- VAR text: Texts.Text; beg, end, time: LONGINT;
- BEGIN
- Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
- IF (S.line#0) OR ((S.class#Texts.Name) & (S.class#Texts.String)) THEN
- Oberon.GetSelection(text, beg, end, time);
- IF time>=0 THEN Texts.OpenScanner(S, text, beg); Texts.Scan(S) END
- END
- END GetArgs;
- PROCEDURE Option(VAR S: Texts.Scanner);
- BEGIN option := 0X;
- Texts.Scan(S);
- IF (S.class=Texts.Char) & (S.c=OptionChar) THEN Texts.Scan(S);
- IF S.class=Texts.Name THEN option := S.s[0]; Texts.Scan(S) END
- END
- END Option;
- (* PROCEDURE QualIdent(VAR name, first, second: ARRAY OF CHAR);
- VAR i, j: INTEGER; ch: CHAR;
- BEGIN
- i:=0; ch:=name[0];
- WHILE (ch#".") & (ch#0X) DO first[i]:=ch; INC(i); ch:=name[i] END;
- first[i]:=0X; INC(i); j:=0; ch:=name[i];
- WHILE ch#0X DO second[j]:=ch; INC(i); INC(j); ch:=name[i] END;
- second[j]:=0X
- END QualIdent; *)
- PROCEDURE QualIdent(VAR name, first, second: ARRAY OF CHAR);
- VAR i, j: INTEGER; ch: CHAR;
- BEGIN
- i:=0; ch:=name[0];
- WHILE (ch#".") & (ch#0X) DO first[i]:=ch; INC(i); ch:=name[i] END;
- first[i]:=0X;
- IF ch#0X THEN
- j:=0; INC(i); ch:=name[i];
- WHILE ch#0X DO second[j]:=ch; INC(i); INC(j); ch:=name[i] END;
- second[j]:=0X
- ELSE second[0]:=0X END
- END QualIdent;
- PROCEDURE ShowDef*;
- VAR
- S: Texts.Scanner;
- mod, dummy: ARRAY 32 OF CHAR;
- obj: Object;
- BEGIN
- GetArgs(S);
- IF (S.class=Texts.Name) OR (S.class=Texts.String) THEN
- QualIdent(S.s, mod, dummy); Option(S);
- Init;
- ReadSym(mod, obj);
- IF ~err THEN
- showObj := FALSE; WriteModule(obj);
- Append(mod, ".Def"); DisplayW(mod)
- END
- END
- END ShowDef;
- PROCEDURE ShowObj*;
- VAR
- S: Texts.Scanner;
- mod, objName, qualid: ARRAY 32 OF CHAR;
- obj: Object;
- BEGIN
- GetArgs(S);
- IF (S.class=Texts.Name) OR (S.class=Texts.String) THEN
- COPY(S.s, qualid); QualIdent(S.s, mod, objName); Option(S);
- Init;
- ReadSym(mod, obj);
- IF ~err THEN
- obj := obj^.link; id := Index(objName);
- WHILE (obj # NIL) & (Diff(id, obj^.name) # 0) DO obj := obj^.right END ;
- IF obj # NIL THEN
- showObj := TRUE; first := TRUE;
- WriteObject(obj, obj^.mode);
- DisplayW(qualid)
- END
- END
- END
- END ShowObj;
- PROCEDURE ShowTree*;
- VAR
- S: Texts.Scanner;
- modName, dummy: ARRAY 32 OF CHAR;
- obj: Object;
- BEGIN
- GetArgs(S); Init;
- WHILE (S.class = Texts.Name) OR (S.class=Texts.String) DO
- QualIdent(S.s, modName, dummy); Option(S);
- ReadSym(modName, obj); IF err THEN RETURN END
- END ;
- WriteRecords(types^.sub, 1);
- DisplayW("Browser.ShowTree")
- END ShowTree;
- PROCEDURE SetExtension*; (* "sym file extension"*)
- VAR S: Texts.Scanner;
- BEGIN GetArgs(S);
- IF S.class = Texts.String THEN COPY(S.s, symFileExt) END
- END SetExtension;
- BEGIN
- Texts.OpenWriter(W);
- InitStruct(undftyp, Undef); InitStruct(notyp, NoTyp);
- InitStruct(stringtyp, String); InitStruct(niltyp, NilTyp);
- symFileExt := ".Sym"
- END Browser.
-